package com.foreveross.project.usercenterserver.oauth2.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.foreveross.project.usercenterserver.common.constant.GlobalConstant;
import com.foreveross.project.usercenterserver.common.constant.ResultCode;
import com.foreveross.project.usercenterserver.common.utils.CodeUtils;
import com.foreveross.project.usercenterserver.common.utils.ContextUtil;
import com.foreveross.project.usercenterserver.exception.CustomException;
import com.foreveross.project.usercenterserver.oauth2.domain.UcAccount;
import com.foreveross.project.usercenterserver.oauth2.domain.UcApp;
import com.foreveross.project.usercenterserver.oauth2.domain.UcTenant;
import com.foreveross.project.usercenterserver.oauth2.dto.AccountDto;
import com.foreveross.project.usercenterserver.oauth2.dto.AppDto;
import com.foreveross.project.usercenterserver.oauth2.enums.DelFlagEnum;
import com.foreveross.project.usercenterserver.oauth2.mapper.UcAccountMapper;
import com.foreveross.project.usercenterserver.oauth2.mapper.UcAppMapper;
import com.foreveross.project.usercenterserver.oauth2.mapper.UcTenantMapper;
import com.foreveross.project.usercenterserver.oauth2.service.IUcAccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreveross.project.usercenterserver.oauth2.service.IUcAppService;
import com.foreveross.project.usercenterserver.oauth2.service.IUcTenantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yz
 * @since 2019-07-22
 */
@Service
public class UcAccountServiceImpl extends ServiceImpl<UcAccountMapper, UcAccount> implements IUcAccountService {

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    private IUcTenantService ucTenantService;

    @Autowired
    private IUcAppService ucAppService;

    @Override
    public UcAccount createAccount(AccountDto accountDto) {
        this.validityData(accountDto);
        UcAccount ucAccount = new UcAccount();
        BeanUtil.copyProperties(accountDto, ucAccount);
        ucAccount.setCreateAt(new Date());
        ucAccount.setCreateBy(ContextUtil.getCurrentUserId());
        ucAccount.setAccountFkId(CodeUtils.getUUID());
        ucAccount.setPassword(passwordEncoder.encode(ucAccount.getPassword()));
        int insert = baseMapper.insert(ucAccount);
        ucAccount.setId(insert);
        return ucAccount;
    }

    @Override
    public UcAccount updateAccount(AccountDto accountDto) {
        this.validityData(accountDto);
        UcAccount account = this.findAccount(accountDto.getAccountFkId());
        String userName = account.getUsername();
        BeanUtil.copyProperties(accountDto, account);
        account.setUsername(userName);
        account.setUpdateAt(new Date());
        account.setUpdateBy(ContextUtil.getCurrentUserId());
        try {
            baseMapper.updateById(account);
        } catch (Exception e) {
            throw new CustomException(GlobalConstant.ERROR_MESSAGE_SAVE_FAIL);
        }
        return account;
    }

    @Override
    public void deleteAccount(String accountFkId) {
        UcAccount account = this.findAccount(accountFkId);
        if (ObjectUtil.isNull(account)) {
            throw new CustomException(GlobalConstant.ERROR_ACCOUNT_NON_EXISTENT_MSG);
        }
        account.setDelFlag(DelFlagEnum.ISDEL.getDelFlag());
        try {
            baseMapper.updateById(account);
        } catch (Exception e) {
            throw new CustomException(GlobalConstant.ERROR_MESSAGE_SAVE_FAIL);
        }

    }

    @Override
    public UcAccount findAccount(String accountFkId) {
        QueryWrapper<UcAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_fk_id", accountFkId);
        UcAccount account = baseMapper.selectOne(queryWrapper);
        return account;
    }

    @Override
    public IPage<AccountDto> queryForPage(Page<AccountDto> page, Map<String, Object> params) {
        return baseMapper.queryForPage(page, params);
    }

    /**
     * 校验
     *
     * @param accountDto
     */
    private void validityData(AccountDto accountDto) {
        //检查数据是否存在
        if (StrUtil.isEmpty(accountDto.getAppFkId()) || StrUtil.isEmpty(accountDto.getTenantFkId())) {
            throw new CustomException(GlobalConstant.ERROR_MESSAGE_PARAMETER_ABSENCE, ResultCode.BAD_REQUEST.getCode());
        }
        //检查应用，租户是否存在
        UcTenant ucTenant = ucTenantService.findTenant(accountDto.getTenantFkId());
        if (ObjectUtil.isNull(ucTenant)) {//检查租户
            throw new CustomException(GlobalConstant.ERROR_TENANT_NON_EXISTENT_MSG);
        }
        UcApp ucApp = ucAppService.findApp(accountDto.getAppFkId());
        if (ObjectUtil.isNull(ucApp)) {//检查应用
            throw new CustomException(GlobalConstant.ERROR_APP_NOT_EXISTENT_MSG);
        }
        //查找该应用是否存在对应用户
        QueryWrapper<UcAccount> ucAccountQueryWrapper = new QueryWrapper<>();
        ucAccountQueryWrapper.eq("tenant_fk_id", accountDto.getTenantFkId());
        ucAccountQueryWrapper.eq("app_fk_id", accountDto.getAppFkId());
        ucAccountQueryWrapper.eq("username", accountDto.getUsername());
        UcAccount ucAccount = baseMapper.selectOne(ucAccountQueryWrapper);
        if (StrUtil.isEmpty(accountDto.getAccountFkId())) {
            //为空则视为新增
            if (ObjectUtil.isNotNull(ucAccount)) {
                throw new CustomException(GlobalConstant.ERROR_ACCOUNT_REPEAT_MSG);
            }
        } else {
            //修改,判断是否当前记录,
            UcAccount account = this.findAccount(accountDto.getAccountFkId());
            if (ObjectUtil.isNull(account)) {
                throw new CustomException(GlobalConstant.ERROR_ACCOUNT_NON_EXISTENT_MSG);
            }
            if (ObjectUtil.isNotNull(ucAccount)) {
                if (!ucAccount.getAccountFkId().equalsIgnoreCase(accountDto.getAccountFkId())) {
                    throw new CustomException(GlobalConstant.ERROR_ACCOUNT_REPEAT_MSG);
                }
            }
        }
    }

}
